package sample.api;

import org.apache.log4j.Logger;
import org.dreamwork.jasmine2.restful.MethodType;
import org.dreamwork.jasmine2.restful.RestfulAPIException;
import org.dreamwork.jasmine2.restful.annotation.*;
import org.dreamwork.util.StringUtil;
import sample.data.Person;
import sample.data.Product;

import javax.servlet.ServletContext;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * Created with IntelliJ IDEA.
 * User: seth.yang
 * Date: 14-11-21
 * Time: 下午5:01
 */
@RestfulAPI (pattern = "product", title="产品相关API")
@Description ("产品相关API")
public class TestAPI {
    private static final Logger logger = Logger.getLogger (TestAPI.class);

    @ContextParameter
    private String storeId;

    @ContextParameter (description = "接口凭证", required = true)
    private String ticket;

    @ContextParameter
    private ServletContext application;

    public String getStoreId () {
        return storeId;
    }

    public void setStoreId (String storeId) {
        this.storeId = storeId;
    }

    public String getTicket () {
        return ticket;
    }

    public void setTicket (String ticket) {
        this.ticket = ticket;
    }

    @BeforeExecute
    public void check () throws RestfulAPIException {
        if (StringUtil.isEmpty (ticket) || ticket.trim ().length () < 3) {
            throw new RestfulAPIException ("Invalid Ticket", 0x1234);
        }
    }

    @BeforeExecute
    public boolean check2 () {
        return ticket.trim ().charAt (0) != 'a';
    }

    @RestfulAPI (
        title = "test api ",
        method = MethodType.POST,
        contextParameters = @ContextParameter (name = "ticket", required = true),
        apiParameters = @APIParameter (name = "product", description = "产品详细信息")
    )
    public Product create (Product product) {
        logger.info (product);
        Integer count = (Integer) application.getAttribute ("count");
        if (count == null) count = 1;
        else count ++;
        application.setAttribute ("count", count);
        product.setId (count);
        return product;
    }

    @RestfulAPI (
            title = "echo api",
            method = MethodType.GET,
            contextParameters = @ContextParameter (name = "ticket", required = true),
            apiParameters = {
            @APIParameter (name = "id"), @APIParameter (name = "name"), @APIParameter (name = "number")
    })
    public Map<String, Object> echo (int id, String name, Double number) {
        Map<String, Object> map = new HashMap<String, Object> ();
        map.put ("id", id);
        map.put ("name", name);
        map.put ("number", number);
        return map;
    }

    @RestfulAPI (
        pattern = "detail",
        title = "产品明细",
        apiParameters = @APIParameter (name = "id", type = int.class, description = "产品ID"),
        result = {
            @ResultField (name = "id", type="number", mandatory = true),
            @ResultField (name = "category", type = "string", mandatory = true, description = "分类"),
            @ResultField (name = "supplier", type = "string", mandatory = true),
            @ResultField (name = "name", type = "string", mandatory = true),
            @ResultField (name = "unit", type = "string", mandatory = true),
            @ResultField (name = "store", type = "number", description = "库存"),
            @ResultField (name = "price", type = "number")
        }
    )
    @Description ("获取指定产品的明细")
    public Product getProduct (int id) throws RestfulAPIException {
        logger.info ("trying to fetch product(id = " + id + ")");

        if (id <= 0)
            throw new RestfulAPIException ("Invalid Product ID", 0x1001);

        Product product = new Product ();
        product.setId (id);
        product.setCategory ("Sea Food");
        product.setName ("Australian Lobster");
        product.setPrice (688);
        product.setStore (99);
        product.setSupplier ("Unknown supplier");
        product.setUnit ("Piece");
        return product;
    }

    @RestfulAPI (pattern = "list", title = "产品查询")
    public List<Product> findProducts (
            @APIParameter (name = "queries", description = "查询条件")
            Map<String, Object> queries) throws RestfulAPIException {
        if (queries.isEmpty ())
            throw new RestfulAPIException ("Invalid Query condition", 0x1002);

        Object o = queries.get ("id");
        List<String> arrays = new ArrayList<String> ();
        if (o != null) {
            if (o.getClass () == String.class) {
                arrays.add ((String) o);
            } else if (o.getClass ().isArray ()) {
                int length = Array.getLength (o);
                for (int i = 0; i < length; i ++)
                    arrays.add ((String) Array.get (o, i));
            }
        }

        if (!arrays.isEmpty ()) {
            List<Product> products = new ArrayList<Product> (arrays.size ());
            for (String s : arrays) {
                int id = Integer.valueOf (s);
                Product product = new Product ();
                product.setId (id);
                product.setSupplier ("Unknown Supplier");
                product.setStore ((int) (Math.random () * 10000));
                product.setPrice ((int) (Math.random () * 1000));
                product.setUnit ("Piece");
                product.setCategory ("Sea Food");
                product.setName ("Product " + id);
                products.add (product);
            }
            return products;
        }

        return null;
    }

    @RestfulAPI (title = "检查指定ID的产品是否存在", forceEncrypt = true, skipBeforeExecute = true)
    @Description ("如果出入的ID为非负整数，这返回 true, 否则返回 false")
    public boolean exists (@APIParameter (name = "id") int id) {
        return id > 0;
    }

    @RestfulAPI (
        title = "complex post api",
        method = MethodType.POST,
        description = "test for complex post aip",
        apiParameters = {
            @APIParameter (name = "id"),
            @APIParameter (name = "person")
        }
    )
    public void complexPost (int id, Person person) {
        logger.info ("id = " + id);
        logger.info ("person = " + person);
    }
}